package cn.sciento.farm.devicemanager.api.jsonrpc.impl;


import cn.sciento.farm.devicemanager.api.jsonrpc.DeviceJsonApi;
import cn.sciento.farm.devicemanager.api.jsonrpc.dto.BatchCreateDeviceDTO;
import cn.sciento.farm.devicemanager.common.constant.DeviceConstant;
import cn.sciento.farm.devicemanager.common.constant.ResultConstant;
import cn.sciento.farm.devicemanager.common.util.ReturnUtil;
import cn.sciento.farm.devicemanager.dao.entity.DevDevice;
import cn.sciento.farm.devicemanager.dao.model.DeviceStatistics;
import cn.sciento.farm.devicemanager.dao.model.ResponseMessage;
import cn.sciento.farm.devicemanager.gateway.downlink.service.MqttBlockedSendManager;
import cn.sciento.farm.devicemanager.gateway.downlink.service.impl.MqttSendService;
import cn.sciento.farm.devicemanager.gateway.model.downlink.DownLinkResult;
import cn.sciento.farm.devicemanager.gateway.model.downlink.LoraWanConfigData;
import cn.sciento.farm.devicemanager.gateway.model.downlink.SciGatewayConfigData;
import cn.sciento.farm.devicemanager.gateway.model.downlink.SciGwBlockConfigData;
import cn.sciento.farm.devicemanager.gateway.model.uplink.DeviceSystemPacket;
import cn.sciento.farm.devicemanager.sensor.*;
import cn.sciento.farm.devicemanager.sensor.Error;
import cn.sciento.farm.devicemanager.service.DeviceService;
import com.alibaba.fastjson.JSON;
import com.googlecode.jsonrpc4j.spring.AutoJsonRpcServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.util.ArrayList;
import java.util.List;

@Service
@AutoJsonRpcServiceImpl
public class DeviceJsonApiImpl implements DeviceJsonApi {
    @Autowired
    DeviceService deviceService;

    @Autowired
    MqttSendService mqttSendService;

    @Autowired
    MqttBlockedSendManager mqttBlockedSendManager;

    @Override
    public ResponseMessage create(DevDevice device) {
        if (StringUtils.isEmpty(device.getName()) || StringUtils.isEmpty(device.getId())
                || StringUtils.isEmpty(device.getLocation())
                || StringUtils.isEmpty(device.getType())
                || device.getLandId() <= 0) {
            return ReturnUtil.getReturnMap(ResultConstant.NULL_PARAMETER);
        } else {
            DevDevice oldDevice = deviceService.getById(device.getId());
            if (oldDevice != null) {
                return ReturnUtil.getReturnMap(ResultConstant.REPEAT_PARAMETER);
            } else {
                device.setCreateTime(System.currentTimeMillis());
                device.setUpdateTime(System.currentTimeMillis());
                device.setId(device.getId().trim().toLowerCase());
                int count = deviceService.insert(device);
                return ReturnUtil.getReturnMap(ResultConstant.SUCCESS, count, device);
            }
        }
    }

    @Override
    public ResponseMessage batchCreate(BatchCreateDeviceDTO deviceDTO) {
        if(deviceDTO.getDeviceList() == null || deviceDTO.getDeviceList().size() == 0){
            return ReturnUtil.getReturnMap(ResultConstant.NULL_PARAMETER);
        }
        List<DevDevice> devDevices = deviceDTO.getDeviceList();
        devDevices.forEach(item->{
            item.setAltitude(100f);
            item.setLocation("113.08603,23.014732");
            item.setSequence(10);
            item.setAreaId(deviceDTO.getAreaId());
            item.setLandId(deviceDTO.getLandId());
            item.setShowType(0);
            item.setType(DeviceConstant.LOEAWAN_NODE);
            this.create(item);
        });
        return  ReturnUtil.getReturnMap(ResultConstant.SUCCESS);
    }

    @Override
    public ResponseMessage update(DevDevice device) {
        if (StringUtils.isEmpty(device.getId())) {
            return ReturnUtil.getReturnMap(ResultConstant.NULL_PARAMETER);
        } else {
            DevDevice devDevice = new DevDevice();
            devDevice.setId(device.getId());
            devDevice.setName(device.getName());
            devDevice.setAltitude(device.getAltitude());
            devDevice.setLocation(device.getLocation());
            devDevice.setLandId(device.getLandId());
            devDevice.setRemark(device.getRemark());
            devDevice.setShowType(device.getShowType());
            devDevice.setSequence(device.getSequence());
            devDevice.setCardNumber(device.getCardNumber());
            int count = deviceService.updateById(devDevice);
            return ReturnUtil.getReturnMap(ResultConstant.SUCCESS, count, device.getId());
        }
    }

    @Override
    public ResponseMessage get(String id) {
        DevDevice devDevice = deviceService.getById(id);
        if (devDevice == null) {
            return ReturnUtil.getReturnMap(ResultConstant.NULL_PARAMETER);
        } else {
            return ReturnUtil.getReturnMap(ResultConstant.SUCCESS, devDevice);
        }
    }

    @Override
    public ResponseMessage list(Integer landId, Integer areaId) {
        List<DevDevice> deviceList = new ArrayList<>();
        if (landId <= 0 && areaId <= 0) {
            return ReturnUtil.getReturnMap(ResultConstant.NULL_PARAMETER);
        } else {
            if (landId > 0) {
                deviceList = deviceService.getByLandId(landId);
            } else {
                deviceList = deviceService.getByAreaId(areaId);

            }
            return ReturnUtil.getReturnMap(ResultConstant.SUCCESS, deviceList);
        }
    }

    @Override
    public ResponseMessage delete(String id) {
        int count = deviceService.deleteById(id);
        return ReturnUtil.getReturnMap(ResultConstant.SUCCESS, count);
    }

    @Override
    public ResponseMessage config(DevDevice devDevice) {
        if(StringUtils.isEmpty(devDevice.getId())){
            return ReturnUtil.getReturnMap(ResultConstant.NULL_PARAMETER);
        }
        DevDevice device = deviceService.getById(devDevice.getId());
        if (device == null){
            return ReturnUtil.getReturnMap(ResultConstant.NULL_PARAMETER);
        }
        String deviceType = device.getType();
        if(deviceType.equals(DeviceConstant.LOEAWAN_NODE)){
            LoraWanConfigData configData = new LoraWanConfigData();
            configData.setConcentrator(device.getId());
            configData.setPeriod( devDevice.getPeriod().shortValue());
            configData.setResponseTime(devDevice.getHeartPeriod().shortValue());
            mqttSendService.send(configData.generate());
            return ReturnUtil.getReturnMap(ResultConstant.SUCCESS);
        }else if(deviceType.equals(DeviceConstant.SCI_GW)){
            DevDevice dev = new DevDevice();
            dev.setId(devDevice.getId());
            dev.setHeartPeriod(devDevice.getHeartPeriod());
            dev.setBaud(devDevice.getBaud());
            dev.setPeriod(devDevice.getPeriod());
            SciGwBlockConfigData sciGwBlockConfigData = new SciGwBlockConfigData();
            sciGwBlockConfigData.setConcentrator(device.getId());
            sciGwBlockConfigData.setBaud(devDevice.getBaud());
            sciGwBlockConfigData.setPeriod(devDevice.getPeriod());
            if(mqttBlockedSendManager.send(sciGwBlockConfigData).getCode() == 1){
                int count = deviceService.updateById(dev);
                return ReturnUtil.getReturnMap(ResultConstant.SUCCESS, count);
            }
        }else {
            return ReturnUtil.getReturnMap(ResultConstant.FAILED);
        }
        return ReturnUtil.getReturnMap(ResultConstant.FAILED);
    }

    @Override
    public ResponseMessage statistics(Integer areaId) {
        DeviceStatistics deviceStatistics = deviceService.getStatistics(areaId);
        return ReturnUtil.getReturnMap(ResultConstant.SUCCESS, deviceStatistics);
    }

    @Override
    public ResponseMessage readParams(String id) {
        DevDevice device = deviceService.getById(id);
        if(device == null){
            return ReturnUtil.getReturnMap(ResultConstant.NULL_PARAMETER);
        }
        SciGwBlockConfigData sciGwBlockConfigData = new SciGwBlockConfigData();
        sciGwBlockConfigData.setConcentrator(device.getId());
        sciGwBlockConfigData.setParam(1);
        DownLinkResult result = mqttBlockedSendManager.send(sciGwBlockConfigData);
        if(result.getCode() != 1){
            return ReturnUtil.getReturnMap(ResultConstant.FAILED);
        }else {
            String deviceSys = result.getData();
            return ReturnUtil.getReturnMap(ResultConstant.SUCCESS, JSON.parseObject(deviceSys, DeviceSystemPacket.class));
        }
    }
}
